from flask import request
from flask_restx import Resource, Namespace, fields
from flask_jwt_extended import create_access_token
from app.utils.response import success_response, error_response
from app.utils.auth import token_required
from app.utils.validators import validate_required_fields, validate_username
from app.services.admin_service import AdminService
from app.swagger_docs import (
    login_request_model, login_response_model, 
    success_response_model, error_response_model,
    admin_model
)

# 创建认证命名空间
auth_ns = Namespace('auth', description='认证相关接口')

# 定义模型
wechat_login_model = auth_ns.model('微信登录请求', {
    'code': fields.String(required=True, description='微信登录code'),
    'nickname': fields.String(description='用户昵称'),
    'avatar': fields.String(description='用户头像'),
    'gender': fields.Integer(description='用户性别:1男,2女')
})

wechat_login_response = auth_ns.model('微信登录响应', {
    'code': fields.Integer(description='状态码'),
    'message': fields.String(description='响应消息'),
    'data': fields.Nested(auth_ns.model('微信登录数据', {
        'token': fields.String(description='JWT令牌'),
        'user_info': fields.Raw(description='用户信息'),
        'is_new_user': fields.Boolean(description='是否为新用户')
    }))
})

send_sms_model = auth_ns.model('发送验证码请求', {
    'phone': fields.String(required=True, description='手机号')
})

send_sms_response = auth_ns.model('发送验证码响应', {
    'code': fields.Integer(description='状态码'),
    'message': fields.String(description='响应消息'),
    'data': fields.Raw(description='数据，一般为null')
})

verify_phone_model = auth_ns.model('验证手机号请求', {
    'phone': fields.String(required=True, description='手机号'),
    'code': fields.String(required=True, description='验证码')
})

verify_phone_response = auth_ns.model('验证手机号响应', {
    'code': fields.Integer(description='状态码'),
    'message': fields.String(description='响应消息'),
    'data': fields.Raw(description='用户信息')
})

refresh_token_response = auth_ns.model('刷新令牌响应', {
    'code': fields.Integer(description='状态码'),
    'message': fields.String(description='响应消息'),
    'data': fields.Nested(auth_ns.model('刷新令牌数据', {
        'token': fields.String(description='新的JWT令牌')
    }))
})

logout_response = auth_ns.model('登出响应', {
    'code': fields.Integer(description='状态码'),
    'message': fields.String(description='响应消息'),
    'data': fields.Raw(description='数据，一般为null')
})

# 接口文档
auth_docs = [
    {
        'name': 'wechat-login',
        'endpoint': '/api/auth/v1/auth/wechat-login',
        'method': 'POST',
        'description': '微信登录',
        'parameters': wechat_login_model,
        'responses': {
            200: ('成功', wechat_login_response),
            400: ('请求错误', None),
            500: ('服务器错误', None)
        },
        'security': None
    },
    {
        'name': 'send-sms',
        'endpoint': '/api/auth/v1/auth/send-sms',
        'method': 'POST',
        'description': '发送短信验证码',
        'parameters': send_sms_model,
        'responses': {
            200: ('成功', send_sms_response),
            400: ('请求错误', None),
            500: ('服务器错误', None)
        },
        'security': None
    },
    {
        'name': 'verify-phone',
        'endpoint': '/api/auth/v1/auth/verify-phone',
        'method': 'POST',
        'description': '验证手机号',
        'parameters': verify_phone_model,
        'responses': {
            200: ('成功', verify_phone_response),
            400: ('请求错误', None),
            401: ('未授权', None),
            500: ('服务器错误', None)
        },
        'security': 'BearerAuth'
    },
    {
        'name': 'logout',
        'endpoint': '/api/auth/v1/auth/logout',
        'method': 'POST',
        'description': '用户登出',
        'parameters': None,
        'responses': {
            200: ('成功', logout_response),
            401: ('未授权', None)
        },
        'security': 'BearerAuth'
    },
    {
        'name': 'refresh',
        'endpoint': '/api/auth/v1/auth/refresh',
        'method': 'POST',
        'description': '刷新令牌',
        'parameters': None,
        'responses': {
            200: ('成功', refresh_token_response),
            401: ('未授权', None)
        },
        'security': 'BearerAuth'
    }
]

@auth_ns.route('/login')
class LoginAPI(Resource):
    """管理员登录接口"""
    
    @auth_ns.doc(
        description='管理员登录',
        responses={
            200: ('登录成功', login_response_model),
            400: ('登录失败', error_response_model)
        }
    )
    @auth_ns.expect(login_request_model, validate=True)
    def post(self):
        """管理员登录"""
        # 验证必填字段
        is_valid, error_msg = validate_required_fields(['username', 'password'])
        if not is_valid:
            return error_response(error_msg, 400)
        
        data = request.get_json()
        username = data.get('username')
        password = data.get('password')
        
        # 验证用户名格式
        if not validate_username(username):
            return error_response('用户名格式不正确', 400)
        
        # 查找管理员
        admin = AdminService.get_by_username(username)
        if not admin:
            return error_response('用户名或密码错误', 400)
        
        # 验证密码
        if not admin.check_password(password):
            return error_response('用户名或密码错误', 400)
        
        # 检查状态
        if not admin.status:
            return error_response('账号已被禁用', 400)
        
        # 生成JWT token（identity必须是字符串）
        access_token = create_access_token(identity=str(admin.id))
        
        return success_response({
            'token': access_token,
            'admin_info': admin.to_dict()
        }, '登录成功')


@auth_ns.route('/logout')
class LogoutAPI(Resource):
    """管理员登出接口"""
    
    @auth_ns.doc(
        description='管理员登出',
        security='Bearer',
        responses={
            200: ('登出成功', success_response_model),
            401: ('未授权', error_response_model)
        }
    )
    @token_required
    def post(self, current_admin):
        """管理员登出"""
        return success_response(message='登出成功')


@auth_ns.route('/info')
class InfoAPI(Resource):
    """获取当前管理员信息接口"""
    
    @auth_ns.doc(
        description='获取当前管理员信息',
        security='Bearer',
        responses={
            200: ('获取成功', success_response_model),
            401: ('未授权', error_response_model)
        }
    )
    @auth_ns.marshal_with(success_response_model)
    @token_required
    def get(self, current_admin):
        """获取当前管理员信息"""
        return success_response(current_admin.to_dict())


@auth_ns.route('/password')
class PasswordAPI(Resource):
    """修改密码接口"""
    
    password_request_model = auth_ns.model('PasswordRequest', {
        'old_password': fields.String(required=True, description='原密码'),
        'new_password': fields.String(required=True, description='新密码')
    })
    
    @auth_ns.doc(
        description='修改密码',
        security='Bearer',
        responses={
            200: ('修改成功', success_response_model),
            400: ('修改失败', error_response_model),
            401: ('未授权', error_response_model)
        }
    )
    @auth_ns.expect(password_request_model, validate=True)
    @token_required
    def put(self, current_admin):
        """修改密码"""
        # 验证必填字段
        is_valid, error_msg = validate_required_fields(['old_password', 'new_password'])
        if not is_valid:
            return error_response(error_msg, 400)
        
        data = request.get_json()
        old_password = data.get('old_password')
        new_password = data.get('new_password')
        
        # 验证旧密码
        if not current_admin.check_password(old_password):
            return error_response('原密码不正确', 400)
        
        # 更新密码
        current_admin.set_password(new_password)
        from app import db
        db.session.commit()
        
        return success_response(message='密码修改成功') 